package com.liushuo.service;

import com.liushuo.entity.Question;
import com.liushuo.dao.QuestionDao;
import com.liushuo.util.ThreadLocalUtil;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.sql.Timestamp;
import java.util.*;

public class QuestionService {
    private final QuestionDao questionDAO = new QuestionDao();
    private static final Random random = new Random();

    // 生成习题集
    public List<Question> generateQuestions(int totalQuestions, int questionsWithParentheses, int gradeLevel) {
        if (totalQuestions <= 0 || questionsWithParentheses < 0 || totalQuestions < questionsWithParentheses || gradeLevel < 1 || gradeLevel > 6) {
            throw new IllegalArgumentException("无效参数");
        }
        if (gradeLevel < 5 && questionsWithParentheses > 0) {
            throw new IllegalArgumentException("不支持的参数组合");
        }

        List<Question> questions = new ArrayList<>();

        int reqMulCount = (int)(totalQuestions * 0.2);
        int reqDivCount = (int)(totalQuestions * 0.2);
        int remainingCount = totalQuestions - reqMulCount - reqDivCount;
        System.out.println("reqMulCount: "+reqMulCount + ", reqDivCount: " + reqDivCount + ", remainingCount: " + remainingCount);

        for (int i = 0; i < totalQuestions; i++) {
            boolean hasParentheses = i < questionsWithParentheses;

            String questionText;

            if (reqMulCount > 0) {
                // 优先生成乘法算式
                do {
                    questionText = generateQuestionText(hasParentheses, gradeLevel);
                } while (!isValidExpression(questionText) || !questionText.contains("*"));
                reqMulCount--;
            } else if (reqDivCount > 0) {
                // 然后生成除法算式
                do {
                    questionText = generateQuestionText(hasParentheses, gradeLevel);
                } while (!isValidExpression(questionText) || !questionText.contains("/"));
                reqDivCount--;
            } else {
                // 最后生成剩余的算式
                do {
                    questionText = generateQuestionText(hasParentheses, gradeLevel);
                } while (!isValidExpression(questionText));
            }

            int answer = getResult(questionText);
            Question question = Question.builder()
                            .questionText(questionText)
                            .answer(answer)
                            .hasParentheses(hasParentheses)
                            .build();


            questions.add(question);


        }


//        Collections.shuffle(questions);

        System.out.println("Generated questions:");
        int i = 0;
        for (Question question : questions) {
            i++;
            System.out.println("["+i+"] "+question.getQuestionText() + " = " + question.getAnswer());
        }
        return questions;
    }

    // 生成算式字符串
    private String generateQuestionText(boolean hasParentheses, int gradeLevel) {
        // 1-2年级2个操作数，3-4年级最多9个操作数
        int numOperands = switch (gradeLevel) {
            case 1, 2 -> 2;
            case 3, 4 -> random.nextInt(2, 5);
            case 5, 6 -> random.nextInt(2, 11);
            default -> throw new IllegalStateException("年级必须在1到6之间");
        };

        if (hasParentheses) {
            if (numOperands == 2) {
                numOperands += random.nextInt(1, 8);
            }
        }

        // 操作数和操作符
        int[] operands = new int[numOperands];
        char[] operators = new char[numOperands - 1];

        operands[0] = random.nextInt(1, 100);

        for (int i = 1; i < numOperands; i++) {
            operands[i] = random.nextInt(1, 100);
            operators[i - 1] = getRandomOperator(operands[i - 1], operands[i]);
        }

        return assembledExpression(operands, operators, hasParentheses);
    }

    // 随机选择操作符
    private char getRandomOperator(int operand1, int operand2) {
        char[] operators = {'+', '-', '*', '/'};
        List<Character> possibleOperators = new ArrayList<>();
        for (char operator : operators) {
            if(isValidOperation(operand1, operand2, operator)) {
                possibleOperators.add(operator);
            }
        }
        return possibleOperators.isEmpty() ? '+' : operators[random.nextInt(possibleOperators.size())];
    }

    // 判断是否是有效的操作符
    private boolean isValidOperation(int operand1, int operand2, char operator) {
        return switch (operator) {
            case '+', '*' -> operand1 != operand2;
            case '-' -> operand1 > operand2;
            case '/' -> operand2 != 0 && operand1 % operand2 == 0;
            default -> false;
        };
    }

    // 组装表达式和括号
    private String assembledExpression(int[] operands, char[] operators, boolean hasParentheses) {
        StringBuilder sb = new StringBuilder();
        int numOperands = operands.length;

        if(hasParentheses && numOperands > 2) {
            int left = random.nextInt(numOperands - 1);
            int right = random.nextInt(left + 1, numOperands);

            for (int i = 0; i < numOperands; i++) {
                if (i == left) sb.append("(");
                sb.append(operands[i]);
                if (i == right) sb.append(")");
                if (i < numOperands - 1) {
                    sb.append(operators[i]);
                }
            }
        } else {
            for (int i = 0; i < numOperands; i++) {
                sb.append(operands[i]);
                if (i < numOperands - 1) {
                    sb.append(operators[i]);
                }
            }
        }
        return sb.toString();
    }

    // 判断表达式结果和括号是否有效
    private boolean isValidExpression(String questionText) {
        try {
            if (questionText.contains("(") && questionText.contains(")")) {
                String questionTextWithoutParentheses = questionText.replaceAll("\\(", "").replaceAll("\\)", "");
                int result = getResult(questionText);
                int resultWithoutParentheses = getResult(questionTextWithoutParentheses);
                return result != resultWithoutParentheses && result < 100 && result > 0;
            } else {
                return getResult(questionText) < 100 && getResult(questionText) > 0;
            }

        } catch (Exception e) {
            return false;
        }
    }
    // 利用js引擎计算结果
    private int getResult(String questionText){
        try {
            ScriptEngineManager manager = new ScriptEngineManager();
            ScriptEngine engine = manager.getEngineByName("JavaScript");
            return (int) engine.eval(questionText);
        } catch (ScriptException e) {
            throw new IllegalArgumentException("无效的算式", e);
        }
    }

    public List<Question> getQuestionsByIds(List<Integer> ids) {
        return questionDAO.getQuestionsByIds(ids);
    }
}
